package cn.gjxblog.nio.network.blocking;

import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 * 一 ：使用NIO 完成网络通信的三哥哥核心
 * 1 通道 （channel） 负责连接
 * 2 缓冲区（Buffer） 负责数据的存取
 * 2 选择（Selector） 是SelectableChannel 多路复用器，用于监控SelectableChanel的IO状况
 *
 * SelectableChannel
 * |--SocketChannel
 * |--ServerSocketChannel
 * |--DatagramChannel
 *
 * |--Pipe.SinkChannel
 * |--Pipe.SourceChannel
 * @author gjx
 * @version v1.0
 * @Description
 * @date 2019/7/24 11:33
 */
public class TestBlockingNIO {
    //客户端
    @Test
    public void Client() throws IOException {
        //1. 获取通道
        SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));

        //2. 分配指定大小的缓冲区
        ByteBuffer buf = ByteBuffer.allocate(1024);

        //3 读取本地文件并发送服务器
        FileChannel inChannel = FileChannel.open(Paths.get("42.png"), StandardOpenOption.READ);

        while (inChannel.read(buf)!= -1){
            buf.flip();
            sChannel.write(buf);
            buf.clear();
        }

        //4 关闭通道
        inChannel.close();

    }

    //服务端
    @Test
    public void server() throws IOException {
        //1 获取通道
        ServerSocketChannel ssChannel = ServerSocketChannel.open();
        //2 绑定连接
        ssChannel.bind(new InetSocketAddress(9898));

        //3 获取客户端连接的通道
        SocketChannel sChannel = ssChannel.accept();

        //4 分配指定大小的缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        FileChannel inChannel = FileChannel.open(Paths.get("45.png"), StandardOpenOption.WRITE,StandardOpenOption.CREATE_NEW);
        //5 读取内容
        while (inChannel.read(buffer)!=-1){
            buffer.flip();
            sChannel.write(buffer);
            buffer.clear();
        }

        buffer.put("服务端接收数据成".getBytes());
        buffer.flip();
        sChannel.write(buffer);

    }
}
